package design.singleton;

import java.io.ObjectStreamException;
import java.io.Serializable;

/**
 * 防止反射和反序列化漏洞
 *
 * 懒汉式（线程安全，调用效率低，可以延时加载）
 * 饿汉式（线程安全，调用效率高，不能延时加载）
 * 双重检测锁式（JVM底层内部模型原因，有漏洞）
 * 静态内部类式（线程安全，调用效率高，可以延时加载）
 * 枚举式（线程安全，调用效率高，不能延时加载，天然防止反射和反序列化漏洞）
 */
public class TestSingleton01 implements Serializable {

    public static TestSingleton01 instance;

//    public static TestSingleton01 instance1 = new TestSingleton01();    //饿汉

    private TestSingleton01(){
        if(instance != null){
            throw new RuntimeException();
        }
    }

    public static TestSingleton01 getInstance(){
        // double checking
        if(instance != null){
            return instance;
        }
        synchronized (TestSingleton01.class) {
            if (null == instance) {
                instance = new TestSingleton01();
            }
        }
        return instance;
    }

    private Object readResolve() throws ObjectStreamException{
        return instance;
    }

    public static void main(String[] args) {
        TestSingleton01 t1 = TestSingleton01.getInstance();
        TestSingleton01 t2 = TestSingleton01.getInstance();
        System.out.println(t1 == t2);
    }
}
